/********************************************
 * 功能说明: 
 * 模块名称: 
 * 系统名称: 
 * 软件版权:
 * 系统版本: 1.0.0
 * 开发人员: zhangfb
 * 开发时间: 2019/3/3 0:51
 * 审核人员: 
 * 相关文档: 
 * 修改记录: 修改日期 修改人员 修改说明
 *********************************************/
package com.hyacinth.utils.http;

import com.alibaba.fastjson.JSON;
import com.hyacinth.constant.HttpCont;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import okhttp3.*;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * OkHttpClient工具类
 * @author zhangfb
 * @version 1.0.0.1
 * @since JDK 1.8
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class OkHttpClientUtils {

    /** 默认配置客户端 **/
    public static final OkHttpClient DEFULT_CLIENT = new OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(10, TimeUnit.SECONDS)
            .writeTimeout(10,TimeUnit.SECONDS)
            .retryOnConnectionFailure(true).build();

    /**
     * http client
     * @return okHttp
     */
    public static OkHttpClient getHttpClient(long connTimeOut, long readTimeOut, long writeTimeOut, boolean reTryConn) {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.connectTimeout(connTimeOut, TimeUnit.SECONDS)
                .readTimeout(readTimeOut, TimeUnit.SECONDS)
                .writeTimeout(writeTimeOut,TimeUnit.SECONDS)
                .retryOnConnectionFailure(reTryConn);
        return builder.build();
    }

    /**
     * 解析请求
     * @param url
     * @param method
     * @param contentType
     * @param content
     * @return
     */
    private static Request buildRequest(String url, HttpCont.HttpMethod method, String contentType, String content) {
        // 解析媒体类型
        MediaType mediaType = MediaType.parse(contentType);
        // 组装请求体
        RequestBody requestBody = RequestBody.create(mediaType, content);
        // 构建请求
        Request.Builder builder = new Request.Builder().url(url);
        switch (method) {
            case GET:
                builder.get();
                break;
            case PUT:
                builder.put(requestBody);
                break;
            case POST:
                builder.post(requestBody);
                break;
            case DELETE:
                builder.delete(requestBody);
                break;
            default:
                throw new RuntimeException("不支持的请求类型");
        }
        return builder.build();
    }

    /**
     * 执行请求
     * @param url
     * @param method
     * @param contentType
     * @param content
     * @return
     */
    public static Response excute(String url, HttpCont.HttpMethod method, String contentType, String content) {
        Request request = buildRequest(url, method, contentType, content);
        return excute(DEFULT_CLIENT, request);
    }

    /**
     * 执行请求
     * @param request 请求
     * @return 响应
     */
    public static Response excute(Request request) {
        return excute(DEFULT_CLIENT, request);
    }

    /**
     * 执行请求
     * @param request 请求
     * @return 响应
     */
    public static <T> T excute(Request request, Class<T> clz) {
        return excute4RespBody(DEFULT_CLIENT, request, clz);
    }

    /**
     * 执行请求,获取响应
     * @param request 请求
     * @return 响应
     */
    public static Response excute(OkHttpClient client, Request request) {
        Response response = null;
        try {
            response = client.newCall(request).execute();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (response != null) {
                response.close();
            }
        }
        return response;
    }

    /**
     * 执行请求
     * @param url
     * @param method
     * @param contentType
     * @param content
     * @return
     */
    public static <T> T excute4RespBody(String url, HttpCont.HttpMethod method, String contentType, String content, Class<T> parseClz) {
        Request request = buildRequest(url, method, contentType, content);
        return excute4RespBody(DEFULT_CLIENT, request, parseClz);
    }

    /**
     * 执行请求,获取响应内容
     * @param request 请求
     * @return 响应内容
     */
    public static <T> T excute4RespBody(OkHttpClient client, Request request, Class<T> clz) {
        ResponseBody body = null;
        try {
            Response response = client.newCall(request).execute();
            if (response != null && response.isSuccessful()) {
                body = response.body();
                if (body != null) {
                    return JSON.parseObject(body.string(), clz);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (body != null) {
                body.close();
            }
        }
        return null;
    }
}
